/**
 * 
 */
package info.niwota.group;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;
import android.widget.Toast;

/**
 * @author qiangli
 * 
 */
// http://groups.google.com/group/android-developers/browse_thread/thread/133816827efc8eb9/577994d1df207bfd
public class ContactAdapter2 extends ContactAdapter {

	public ContactAdapter2() {
	}

	@Override
	public Intent getIntent() {
		return (new Intent(Intent.ACTION_PICK,
				ContactsContract.Contacts.CONTENT_URI));
	}
		
	@Override
	protected void loadContactsInConact(Context ctx, Set<EmailContact> contacts) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { 
				ContactsContract.Data.RAW_CONTACT_ID,
				ContactsContract.Contacts.CONTACT_ID,
				ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.Contacts.STARRED,
				ContactsContract.Contacts.LAST_TIME_CONTACTED,
				ContactsContract.Contacts.TIMES_CONTACTED,
				ContactsContract.Data.MIMETYPE,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String by = ContactsContract.Contacts.DISPLAY_NAME + " ASC ";
		String sel = ContactsContract.Data.MIMETYPE + " in (? , ?)";
		String[] args = new String[] {
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, by);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			//
			int colCid = c.getColumnIndex(ContactsContract.Contacts.CONTACT_ID);
			int colId = c.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
			int colName = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
			int colStar = c.getColumnIndex(ContactsContract.Contacts.STARRED);
			int colLastTime = c
					.getColumnIndex(ContactsContract.Contacts.LAST_TIME_CONTACTED);
			int colTimes = c
					.getColumnIndex(ContactsContract.Contacts.TIMES_CONTACTED);
			int colEmail = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			//
			String prev = "";
			EmailContact ec = null;
			ArrayList<String> el = new ArrayList<String>(); // emails
			do {
				String n = c.getString(colName);
				if (n.equals(prev)) {
					String s = c.getString(colEmail);
					//
					if (!el.contains(s)) {
						el.add(s);
					}
				} else {
					// new entry
					if (ec != null) {
						ec.emails = el.toArray(new String[0]);
						contacts.add(ec);
					}
					//
					ec = new EmailContact();
					el.clear();
					prev = n;
					//
					ec.cid = c.getLong(colCid);
					ec.id = c.getLong(colId);
					ec.name = n;
					ec.starred = c.getInt(colStar);
					ec.lastTime = c.getLong(colLastTime);
					ec.times = c.getInt(colTimes);
					//
					String s = c.getString(colEmail);
					el.add(s);
					//
				}
			} while (c.moveToNext());
			
			if (ec != null) {
				ec.emails = el.toArray(new String[0]);
				contacts.add(ec);
			}
		} finally {
			c.close();
		}
	}

	@Override
	protected void loadAddressesInConact(Context context, Set<EmailAddress> addresses) {
		//
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Data._ID,
				ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String by = ContactsContract.Data._ID + " ASC ";
		String sel = ContactsContract.Data.MIMETYPE + " in (? , ?)";
		String[] args = new String[] {
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = context.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, by);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			//
			int colName = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
			int colEmail = c
					.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			//
			Set<EmailAddress> al = new HashSet<EmailAddress>();
			do {
				String a = c.getString(colEmail);
				String n = c.getString(colName);
				try {
					EmailAddress ia = new EmailAddress(a, n);
					al.add(ia);
					//
				} catch (Exception e) {
					// e.printStackTrace();
				}
			} while (c.moveToNext());
			addresses.addAll(al);
		} finally {
			c.close();
		}
		//
	}

	@Override
	protected Bitmap loadContactPhoto(Context context, long id, int res) {
		Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
		ContentResolver cr = context.getContentResolver();
		InputStream input = openContactPhotoInputStream(cr, uri);
		if (input == null) {
			return BitmapFactory.decodeResource(context.getResources(), res);
		}
		return BitmapFactory.decodeStream(input);
	}

	private static InputStream openContactPhotoInputStream(ContentResolver cr,
			Uri contactUri) {
		Uri photoUri = Uri
				.withAppendedPath(contactUri, ContactsContract.Photo.CONTENT_DIRECTORY);
		if (photoUri == null) {
			return null;
		}
		Cursor c = cr.query(photoUri,
				new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO },
				null, null, null);
		try {
			if (c == null || !c.moveToNext()) {
				return null;
			}
			byte[] data = c.getBlob(0);
			if (data == null) {
				return null;
			}
			return new ByteArrayInputStream(data);
		} finally {
			if (c != null) {
				c.close();
			}
		}
	}

	@Override
	protected void addEmailToContact(Context ctx, long id, String[] emails) {
		ContentResolver cr = ctx.getContentResolver();
		ContentValues v = new ContentValues();
		for (int i = 0; i < emails.length; i++) {
			v.put(ContactsContract.Data.RAW_CONTACT_ID, id);
			v.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
			v.put(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_OTHER);
			v.put(ContactsContract.CommonDataKinds.Email.ADDRESS, emails[i]);
			cr.insert(ContactsContract.Data.CONTENT_URI, v);
		}
	}

	@Override
	protected boolean hasEmailInContact(Context context, String email) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] {
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String sel = ContactsContract.CommonDataKinds.Email.ADDRESS + "= ?";
		String[] args = new String[] { email };
		ContentResolver cr = context.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, null);
		if (c == null) {
			return false;
		}
		try {
			boolean has = (c.moveToFirst());
			//
			return has;
		} finally {
			c.close();
		}
	}

	@Override
	protected long getContactId(Context ctx, String name) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { 
				ContactsContract.Data.RAW_CONTACT_ID,
				ContactsContract.Contacts.DISPLAY_NAME};
		Cursor c = ctx.getContentResolver().query(uri, proj,
				ContactsContract.Contacts.DISPLAY_NAME + " = ?", new String[] { name },
				null);
		if (c == null) {
			return -1;
		}
		try {
			if (!c.moveToFirst()) {
				return -1;
			}
			// return the first one found
			int idCol = c.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
			long id = c.getLong(idCol);
			//
			return id;
		} finally {
			c.close();
		}
	}

	@Override
	protected String[] getEmailsInContact(Context ctx, String name) {
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String sel = ContactsContract.Contacts.DISPLAY_NAME + " = ? AND "
				+ ContactsContract.Data.MIMETYPE + " in (? , ?)";
		String[] args = new String[] { name,
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, null);
		if (c == null) {
			return null;
		}
		try {
			if (!c.moveToFirst()) {
				return null;
			}
			Set<String> set = new HashSet<String>();
			int col = c.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			while (c.moveToNext()) {
				String email = c.getString(col);
				set.add(email);
			}
			return set.toArray(new String[0]);
		} finally {
			c.close();
		}
	}

	@Override
	public void saveAsContact(Context ctx, String name, int star, String[] emails) {
		// not supported due to 2.x api change/contact aggregation
		Toast.makeText(ctx, "Not supported on Android 2.x", Toast.LENGTH_LONG).show();
	}

	@Override
	protected void loadGroupNamesInConact(Context ctx, Set<String> names) {
//		final Uri uri = ContactsContract.Data.CONTENT_URI;
//		final String DN = ContactsContract.Contacts.DISPLAY_NAME;
//		final String[] proj = new String[] { DN };
//		final String sel = DN + " like ?";
//		final String[] args = new String[] { "@%" };
//		final String by = DN + " ASC ";
//		final ContentResolver cr = ctx.getContentResolver();
//		Cursor c = cr.query(uri, proj, sel, args, by);
		//
		Uri uri = ContactsContract.Data.CONTENT_URI;
		String[] proj = new String[] { ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Email.ADDRESS };
		String sel = ContactsContract.Contacts.DISPLAY_NAME + " like ? AND "
				+ ContactsContract.Data.MIMETYPE + " in (? , ?)";
		String[] args = new String[] { "@%",
				ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE };
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(uri, proj, sel, args, null);
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			int colName = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
			int colEmail = c.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
			do {
				String a = c.getString(colEmail);
				if (TextUtils.isEmpty(a)) {
					continue;
				}
				String n = c.getString(colName);
				names.add(n);
			} while (c.moveToNext());
		} finally {
			c.close();
		}
	}
}
